package appletencriptar.encriptacion.Encoder;

import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.IOException;

public abstract class CharacterEncoder
{
protected PrintStream pStream;
abstract protected int bytesPerAtom();
abstract protected int bytesPerLine();

protected void encodeBufferPrefix(OutputStream aStream) throws IOException
{
   pStream = new PrintStream(aStream);
}

protected void encodeLinePrefix(OutputStream aStream, int aLength) throws IOException
{
}

protected void encodeBufferSuffix(OutputStream aStream) throws IOException
{
}

protected void encodeLineSuffix(OutputStream aStream) throws IOException
{
  pStream.println();
}


public String encode(byte aBuffer[])
{
   ByteArrayOutputStream outStream = new ByteArrayOutputStream();
   ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
   try {
         encode(inStream, outStream);
        } 
   catch (Exception IOException)
   {
    return null;
   }
   return (outStream.toString());
}

public void encode(InputStream inStream, OutputStream outStream) throws IOException
{
                int j;
                int numBytes;
                byte tmpbuffer[] = new byte[bytesPerLine()];

                encodeBufferPrefix(outStream);

                while (true) {
                    numBytes = readFully(inStream, tmpbuffer);
                    if (numBytes == -1) {
                        break;
                    }
                    encodeLinePrefix(outStream, numBytes);
                    for (j = 0; j < numBytes; j += bytesPerAtom()) {

                        if ((j + bytesPerAtom()) <= numBytes) {
                            encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
                        } else {
                            encodeAtom(outStream, tmpbuffer, j, (numBytes) - j);
                        }
                    }
                    if (numBytes <= bytesPerLine()) {
                        break;
                    } else {
                        encodeLineSuffix(outStream);
                    }
               }
                encodeBufferSuffix(outStream);
            }

abstract protected void encodeAtom(OutputStream aStream,
                    byte someBytes[], int anOffset, int aLength)
                    throws IOException;


protected int readFully(InputStream in, byte buffer[]) throws java.io.IOException
{
               for (int i = 0; i < buffer.length; i++) {
                    int q = in.read();
                    if (q == -1)
                        return i;
                   buffer[i] = (byte) q;
                }
                return buffer.length;
            }

}
